package org.finesys.common.security.core.util;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.finesys.common.security.core.jackson.Auth2Jackson2Module;
import org.finesys.common.security.core.module.AuthUser;
import org.springframework.security.core.Authentication;

import java.util.Set;

@Slf4j
public class OAuth2JacksonUtils {
    /**
     * 解析器
     * -- GETTER --
     * 获取ObjectMapper 对象
     */
    @Getter
    private static ObjectMapper objectMapper;

    static {
        objectMapper = new ObjectMapper();
        // 指定要序列化的域
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 不将日期写为时间戳
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        // 忽略未知属性
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        // 对象为空时不可序列化
        objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        // 记录被序列化的类型信息
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL,
                JsonTypeInfo.As.PROPERTY);
        // null 值不序列化
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        // 处理自定义module
        objectMapper.registerModule(new Auth2Jackson2Module());
    }

    /**
     * 转换成set
     */
    public static Set<String> jsonNodeToSet(JsonNode jsonNode) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.convertValue(jsonNode, Set.class);
    }

    /**
     * 转换成 Authentication
     */
    public static Authentication jsonNodeToAuthentication(JsonNode jsonNode) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.treeToValue(jsonNode, Authentication.class);
    }

    /**
     * 转换json对象
     */
    public static String toJsonString(Object obj) {
        try {
            return objectMapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.error("对象转JSON失败：{}", e.getMessage());
            throw new RuntimeException(e);
        }

    }

    /**
     * 转换json对象
     */
    public static Object toJsonObject(String value, Class<AuthUser> classz) {
        try {
            return objectMapper.readValue(value, classz);
        } catch (JsonProcessingException e) {
            log.error("JSON转对象失败：{}", e.getMessage());
            throw new RuntimeException(e);
        }

    }

}
